import time
from appium import webdriver
import asyncio
import os
import cv2
import numpy as np
import re
import requests
import aiohttp

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from appium.webdriver.common.mobileby import MobileBy
from selenium.common.exceptions import TimeoutException
from appium.webdriver.common.touch_action import TouchAction


# 设定要测试的 Appium Server
server = 'http://localhost:4723/wd/hub'
desired_caps = {
    'platformName': 'Android',
    'deviceName': 'd8f9a249',  # 设备 ID，使用 cmd 中 adb devices 命令得到
    'platformVersion': '8.0.0',  # 设备版本号，在手机设置中查看
    'noReset': True,  # 默认是false，清空数据
    'appPackage': 'com.tencent.mm',
    'appActivity': '.ui.LauncherUI',
}

# 连接 Appium Server 并启动微信
driver = webdriver.Remote(server, desired_caps)

# 等待元素出现 搜索按钮
wait = WebDriverWait(driver, 20)
element = wait.until(EC.visibility_of_element_located(
    (By.ID, "com.tencent.mm:id/f15")))

print('微信启动成功！')
print('开始监听消息！')


async def detection_message():
    while True:
        try:
            # 等待元素出现，超时时间设置为无限期
            wait = WebDriverWait(driver, 20)
            element = wait.until(EC.visibility_of_element_located(
                (By.ID, "com.tencent.mm:id/l0c")))
        except TimeoutException:
            print("等待超时！继续等待...")
            await asyncio.sleep(1)  # 等待1秒钟
        except:
            print("其他异常！")
            # 关闭应用
            driver.quit()
        else:
            # 找到元素
            print("有新消息！")
            # 等待元素处理完成
            await handle_msg()


# 消息处理流程
async def handle_msg():
    print("开始处理消息...")
    await asyncio.sleep(1)
    # 所有需要处理的消息记录
    elements = driver.find_elements(MobileBy.ID, 'com.tencent.mm:id/kmv')
    # 点击第一个消息
    elements[0].click()
    await asyncio.sleep(2)
    # 文本框
    wait = WebDriverWait(driver, 20)
    text_input = wait.until(EC.visibility_of_element_located(
        (MobileBy.ID, 'com.tencent.mm:id/b4a')))

    # 验证用户消息 消息内容讲复制到剪切板
    chat_content = await message_type()

    # 获取用户名
    uName = driver.find_element(
        MobileBy.ID, "com.tencent.mm:id/ko4").text

    # 回复用户
    try:
        response = await asyncio.wait_for(send_reply(uName, chat_content), timeout=15)
    except asyncio.TimeoutError:
        response = "服务响应超时"

    print(response)
    text_input.send_keys(response)

    await asyncio.sleep(2)
    # 等待发送按钮出现 点击发送按钮
    wait = WebDriverWait(driver, 20)
    send_button = wait.until(EC.visibility_of_element_located(
        (MobileBy.ID, "com.tencent.mm:id/b8k")))
    await asyncio.sleep(1)
    send_button.click()
    await asyncio.sleep(1)
    driver.back()

 # 点击复制后，对比模板图，点击相应位置


# 判断消息类型
async def message_type():
    # 是否可执行的消息类型 语音 文字 官方表情
    isOk = False
    text_element = None
    try:
        text_element = driver.find_elements(
            MobileBy.ID, "com.tencent.mm:id/hp")[-1].find_element(MobileBy.ID, "com.tencent.mm:id/b4b")
        isOk = True
    except:
        isOk = False

    if isOk:
        try:
            # 判断是否语音消息 即 1"、2"等等的 数字+"的字符类型
            test = re.match(r"^\d+\"$", text_element.text)
            if test:
                # 点击转文字按钮
                driver.find_element(
                    MobileBy.ID, "com.tencent.mm:id/b5f").click()
                await asyncio.sleep(3)  # 等待 3 秒钟
                chat_text = driver.find_element(
                    MobileBy.ID, "com.tencent.mm:id/b9s").text
                # 等待文字出现后返回
                return chat_text
            else:
                return text_element.text
        except:
            return "程序异常！"
    else:
        return "不支持图片、文件等类型！"


# 回复用户
async def send_reply(uname, content):
    async with aiohttp.ClientSession() as session:
        async with session.get('http://127.0.0.1:8000/chat', params={'uname': uname, 'content': content}) as response:
            if response.status == 200:
                print("回复成功")
            else:
                print("回复失败，错误码:", response.status)
            return await response.text()


# 启动协程
asyncio.run(detection_message())
